package com.weiawei.ui;

import com.weiawei.Dialog.*;
import com.weiawei.net.*;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.io.IOException;
import java.net.SocketException;
import java.net.UnknownHostException;

public class PVPMainBoard extends MainBoard {
    //    游戏界面实例
    private PVPChessBoard chessBoard;
    //    界面按键
    protected JButton buttonStart;
    protected JButton buttonCreate;
    protected JButton buttonJoin;
    protected JButton buttonBack;
    protected JButton buttonExit;
    //    对话框
    private BackDialog backDialog;
    private CreateDialog createDialog;
    private JoinDialog joinDialog;
    private LocalHostIPDialog localHostIPDialog;
    private RepentanceDialog repentanceDialog;
    //    用户身份端
    private Server server;
    private Client client;
    private NetContainer netContainer;
    private Thread serverThread;
    private Thread clientThread;
    //    游戏进程标签
    private JLabel processLabel;
    //    执棋选择线程
    private RoleChoose roleChoose;
    private Thread roleChooseThread;

    /**
     * 初始化PVPMainBoard
     *
     * <p>PVPMainBoard是MainBoard的子类
     * 该界面为人人对弈界面
     * 通过调用MainBoard的构造函数来构造PVPMainBoard的实例</p>
     */
    public PVPMainBoard() {
        super();
        this.initBoard();
    }

    /**
     * 初始化界面的样式
     *
     * <p>包括棋盘和创建房间、加入房间、开始游戏、悔棋、返回五个按钮</p>
     */
    public void initBoard() {
        chessBoard = new PVPChessBoard(this);
        buttonStart = new JButton("开始游戏");
        buttonCreate = new JButton("创建房间");
        buttonJoin = new JButton("加入房间");
        buttonBack = new JButton("悔    棋");
        buttonExit = new JButton("返    回");
        processLabel = new JLabel();
        backDialog = new BackDialog(this, "返回菜单", true);
        createDialog = new CreateDialog(this, "创建房间", true);
        joinDialog = new JoinDialog(this, "加入房间", true);
        localHostIPDialog = new LocalHostIPDialog(this, "新建房间", true);
        roleChoose = null;
        roleChooseThread = null;

        //    设置棋盘
        chessBoard.setClickable(CAN_NOT_CLICK);
        chessBoard.setBounds(0, 30, 600, 600);
        chessBoard.setVisible(true);

        //    设置按钮
        buttonStart.setBounds(600, 400, 200, 50);
        buttonBack.setBounds(600, 460, 200, 50);
        buttonCreate.setBounds(600, 400, 200, 50);
        buttonJoin.setBounds(600, 460, 200, 50);
        buttonExit.setBounds(600, 520, 200, 50);
        setButtonStyle(buttonStart);
        setButtonStyle(buttonBack);
        setButtonStyle(buttonCreate);
        setButtonStyle(buttonJoin);
        setButtonStyle(buttonExit);
        buttonBack.setVisible(false);
        buttonStart.setVisible(false);

        //    设置标签
        processLabel.setFont(new Font(Font.DIALOG_INPUT, Font.BOLD, 20));
        processLabel.setText("等待游戏创建...");
        processLabel.setBounds(600, 300, 200, 100);

        //    添加组件
        this.add(chessBoard);
        this.add(processLabel);
        this.add(buttonCreate);
        this.add(buttonJoin);
        this.add(buttonStart);
        this.add(buttonBack);
        this.add(buttonExit);
    }

    /**
     * 创建房间事件
     */
    private void creatEvent() {
        try {
            server = new Server(this);
            serverThread = new Thread(server);
            serverThread.start();
            netContainer = server;
            localHostIPDialog.getLocalHostLabel().setText("本地IP为：" + server.getLocalHostIP());
            processLabel.setText("等待其他玩家加入");
            buttonCreate.setEnabled(false);
            buttonJoin.setEnabled(false);
        } catch (UnknownHostException | SocketException unknownHostException) {
            unknownHostException.printStackTrace();
            localHostIPDialog.getLocalHostLabel().setText("创建房间失败，请重试。");
        }
        localHostIPDialog.setVisible(true);
        if (localHostIPDialog.getMessage() == LocalHostIPDialog.confirm) {
            localHostIPDialog.setVisible(false);
        }
    }

    /**
     * 加入房间事件
     */
    private void joinEvent() {
        try {
            client = new Client(joinDialog.getTextField().getText(), this);
            clientThread = new Thread(client);
            clientThread.start();
            netContainer = client;
            buttonCreate.setEnabled(false);
            buttonJoin.setEnabled(false);
        } catch (Exception exception) {
            localHostIPDialog.getLocalHostLabel().setText("加入该房间失败，请重试。");
            localHostIPDialog.setVisible(true);
            if (localHostIPDialog.getMessage() == LocalHostIPDialog.confirm) {
                localHostIPDialog.setVisible(false);
            }
        }
    }

    /**
     * 游戏开始事件
     */
    private void startEvent() throws IOException {
        buttonStart.setEnabled(false);
        buttonBack.setEnabled(true);
        //    等待对方准备
        processLabel.setText("等待对方准备");
        roleChoose = new RoleChoose(this, netContainer);
        roleChooseThread = new Thread(roleChoose);
        roleChooseThread.start();
    }

    /**
     * 为服务器和客户端返回按钮实例
     *
     * @return 开始按钮实例
     */
    public JButton getButtonStart() {
        return buttonStart;
    }

    /**
     * 为服务器和客户端返回按钮实例
     *
     * @return 创建房间按钮实例
     */
    public JButton getButtonCreate() {
        return buttonCreate;
    }

    /**
     * 为服务器和客户端返回按钮实例
     *
     * @return 加入房间按钮实例
     */
    public JButton getButtonJoin() {
        return buttonJoin;
    }

    /**
     * 为服务器和客户端返回按钮实例
     *
     * @return 悔棋按钮实例
     */
    public JButton getButtonBack() {
        return buttonBack;
    }

    /**
     * 为服务器和客户端返回对话框实例
     *
     * @return 对话框实例
     */
    public LocalHostIPDialog getLocalHostIPDialog() {
        return localHostIPDialog;
    }

    /**
     * 为服务器和客户端返回标签实例
     *
     * @return 标签实例
     */
    public JLabel getProcessLabel() {
        return processLabel;
    }

    /**
     * 为服务器和客户端返回棋盘实例
     *
     * @return 棋盘实例
     */
    public PVPChessBoard getChessBoard() {
        return chessBoard;
    }


    /**
     * 获取服务器线程
     *
     * @return 服务器线程
     */
    public Thread getServerThread() {
        return serverThread;
    }

    /**
     * 获取客户端线程
     *
     * @return 客户端线程
     */
    public Thread getClientThread() {
        return clientThread;
    }

    /**
     * 获取服务器或客户端
     *
     * @return 服务器或客户端
     */
    public NetContainer getNetContainer() {
        return netContainer;
    }

    /**
     * 通过用户点击的按键来相应不同的事件
     *
     * <p>当用户点击创建房间时将会创建相应房间
     * 当用户点击加入房间是将会加入相应房间
     * 当用户点击开始游戏时会将游戏启动，此时开始游戏按钮不可再点击
     * 当用户点击悔棋时会退回到上一步
     * 当用户点击返回时会返回到开始菜单</p>
     *
     * @param e 用户点击的按键
     */
    @Override
    public void actionPerformed(ActionEvent e) {
        if (e.getSource() == super.getCloseButton()) {
            exitDialog.setVisible(true);
            if (exitDialog.getMessage() == ExitDialog.exit) {
                System.exit(0);
            }
        } else if (e.getSource() == super.getSmallButton()) {
            setExtendedState(ICONIFIED);
        } else if (e.getSource() == buttonCreate) {
            createDialog.setVisible(true);
            if (createDialog.getMessage() == CreateDialog.create) {
                this.creatEvent();
            }
        } else if (e.getSource() == buttonJoin) {
            joinDialog.setVisible(true);
            if (joinDialog.getMessage() == JoinDialog.confirm) {
                this.joinEvent();
            }
        } else if (e.getSource() == buttonStart) {
            try {
                this.startEvent();
            } catch (IOException ioException) {
                ioException.printStackTrace();
                processLabel.setText("游戏异常");
            }
        } else if (e.getSource() == buttonBack) {
            if (chessBoard.clickable) {
                repentanceDialog = new RepentanceDialog(this, "悔棋", true, true);
                repentanceDialog.setVisible(true);
                if (repentanceDialog.getMessage() == RepentanceDialog.repentance) {
                    try {
                        netContainer.getOut().writeUTF("Repentance");
                    } catch (IOException ioException) {
                        ioException.printStackTrace();
                    }
                    chessBoard.setClickable(false);
                    new Thread(new PlayChess(this, netContainer)).start();
                    processLabel.setText("等待对方回应");
                }
            }
        } else if (e.getSource() == buttonExit) {
            backDialog.setVisible(true);
            if (backDialog.getMessage() == BackDialog.back) {
                if (netContainer != null && netContainer.getOut() != null) {
                    try {
                        netContainer.getOut().writeUTF("Exit");
                    } catch (IOException ioException) {
                        ioException.printStackTrace();
                    }
                }
                if (serverThread != null) {
                    server = null;
                    netContainer = null;
                    serverThread.interrupt();
                } else if (clientThread != null) {
                    client = null;
                    netContainer = null;
                    clientThread.interrupt();
                }
                this.dispose();
                new InitialMenu();
            }
        }
    }
}
